package com.googlecode.gendevcode.service.basic;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.UUID;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 基础事件类
 * @author devilishking
 *
 */
public abstract class ServiceSupport<T> {
	/**
	 * 日志对象
	 */
	private Log log = LogFactory.getLog(getClass());
	/**
	 * 结束标志
	 */
	public static final int FLAG_END = -1;
	
	//region 通用日志处理方法
	/**
	 * 设置信息类型的日志
	 * @param msg 日志
	 */
	public void setInfo(String msg){
		if (log.isInfoEnabled()) log.info(msg);
	}
	
	/**
	 * 设置信息类型的日志
	 * @param msg 日志
	 * @param e   错误类
	 */
	public void setInfo(String msg, Throwable e){
		if (log.isInfoEnabled()) log.info(msg, e);
	}
	
	/**
	 * 设置警告类型的日志
	 * @param msg 日志
	 */
	public void setWarn(String msg){
		if (log.isWarnEnabled()) log.warn(msg);
	}
	
	/**
	 * 设置警告类型的日志
	 * @param msg 日志
	 * @param e   错误类
	 */
	public void setWarn(String msg, Throwable e){
		if (log.isWarnEnabled()) log.warn(msg, e);
	}
	
	/**
	 * 设置错误类型的日志
	 * @param msg 日志
	 */
	public void setError(String msg){
		if (log.isErrorEnabled()) log.error(msg);
	}
	
	/**
	 * 设置错误类型的日志
	 * @param msg 日志
	 * @param e   错误类
	 */
	public void setError(String msg, Throwable e){
		if (log.isErrorEnabled()) log.error(msg, e);
	}
	
	/**
	 * 设置调试类型的日志
	 * @param msg 日志
	 */
	public void setDebug(String msg){
		if (log.isDebugEnabled()) log.debug(msg);
	}
	
	/**
	 * 设置调试类型的日志
	 * @param msg 日志
	 * @param e   错误类
	 */
	public void setDebug(String msg, Throwable e){
		if (log.isDebugEnabled()) log.debug(msg, e);
	}
	
	/**
	 * 设置失败类型的日志
	 * @param msg 日志
	 */
	public void setFatal(String msg){
		if (log.isFatalEnabled()) log.fatal(msg);
	}
	
	/**
	 * 设置失败类型的日志
	 * @param msg 日志
	 * @param e   错误类
	 */
	public void setFatal(String msg, Throwable e){
		if (log.isFatalEnabled()) log.fatal(msg, e);
	}
	
	/**
	 * 设置跟踪类型的日志
	 * @param msg 日志
	 */
	public void setTrace(String msg){
		if (log.isTraceEnabled()) log.trace(msg);
	}
	
	/**
	 * 设置跟踪类型的日志
	 * @param msg 日志
	 * @param e   错误类
	 */
	public void setTrace(String msg, Throwable e){
		if (log.isTraceEnabled()) log.trace(msg, e);
	}
	//endregion

	//region 通用获取控制台输入信息的方法
	/**
	 * 获得控制台输入字符串值
	 * @param msg		        提示信息
	 * @return
	 * @throws IOException
	 */
	public String inputStr(String msg){
		return input(msg, null);
	}

	/**
	 * 获得控制台输入字符串值
	 * @param msg		        提示信息
	 * @param defaultValue 默认值
	 * @return
	 * @throws IOException
	 */
	public String inputStr(String msg, String defaultValue){
		return input(msg, defaultValue);
	}
	
	/**
	 * 获得控制台输入整数值
	 * @param msg		       提示信息
	 * @return
	 * @throws IOException
	 */
	public int inputInt(String msg){
		return inputInt(msg, null);
	}
	
	/**
	 * 获得控制台输入整数值
	 * @param msg		       提示信息
	 * @param defaultValue 默认值
	 * @return
	 * @throws IOException
	 */
	public int inputInt(String msg, Integer defaultValue){
		String str = input(msg, defaultValue);
		try{
			return Integer.parseInt(str);
		}
		catch (Exception e) {
			setError(String.format("%0$s不是有效整数!", str), e);
			return inputInt(msg, defaultValue);
		}
	}
	
	/**
	 * 获得控制台输入整数值
	 * @param msg		        提示信息
	 * @return
	 * @throws IOException
	 */
	public Long inputLong(String msg){
		return inputLong(msg, null);
	}
	
	/**
	 * 获得控制台输入整数值
	 * @param msg		        提示信息
	 * @param defaultValue 默认值
	 * @return
	 * @throws IOException
	 */
	public Long inputLong(String msg, Long defaultValue){
		String str = input(msg, defaultValue);
		try{
			return Long.parseLong(str);
		}
		catch (Exception e) {
			setError(String.format("%0$s不是有效长整数!", str), e);
			return inputLong(msg, defaultValue);
		}
	}
	
	/**
	 * 获得控制台输入浮点值
	 * @param msg		        提示信息
	 * @return
	 * @throws IOException
	 */
	public Double inputDouble(String msg){
		return inputDouble(msg, null);
	}
	
	/**
	 * 获得控制台输入浮点值
	 * @param msg		        提示信息
	 * @param defaultValue 默认值
	 * @return
	 * @throws IOException
	 */
	public Double inputDouble(String msg, Double defaultValue){
		String str = input(msg, defaultValue);
		try{
			return Double.parseDouble(str);
		}
		catch (Exception e) {
			setError(String.format("%0$s不是有效浮点数!", str), e);
			return inputDouble(msg, defaultValue);
		}
	}
	
	/**
	 * 获得控制台输入布尔值
	 * @param msg		        提示信息
	 * @return
	 * @throws IOException
	 */
	public Boolean inputBoolean(String msg){
		return inputBoolean(msg, null);
	}
	
	/**
	 * 获得控制台输入浮点值
	 * @param msg		        提示信息
	 * @param defaultValue 默认值
	 * @return
	 * @throws IOException
	 */
	public Boolean inputBoolean(String msg, Boolean defaultValue){
		String str = input(msg, defaultValue);
		try{
			return Boolean.parseBoolean(str);
		}
		catch (Exception e) {
			setError(String.format("%0$s不是有效布尔型值!", str), e);
			return inputBoolean(msg, defaultValue);
		}
	}
	
	/**
	 * 获得控制台输入值
	 * @param msg		        提示信息
	 * @param defaultValue 默认值
	 * @return
	 */
	private String input(String msg, Object defaultValue){
		try{
			BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
			System.out.println();
			System.out.print(msg);
			String str = in.readLine().trim();
			if ("".equals(str)){
				return defaultValue == null ? input(msg, defaultValue) : defaultValue.toString();
			}
			else{
				return str;
			}
		}
		catch (Exception e) {
			setError(e.getMessage(), e);
			return input(msg, defaultValue);
		}
	}
	//endregion

	//region 通用获取新ID方法
	/**
	 * 获取新ID
	 */
	public String getNewId(){
		return UUID.randomUUID().toString();
	}
	//endregion
}